<template>
  <div id="home">
    <!-- 顶部导航模块 -->
    <nav-bar class="home-nav">
      <h2 slot="center" class="center">购物街</h2>
    </nav-bar>
    <tab-control
      :titles="['流行', '新款', '精选']"
      :class="{ tabControl: isTabFixes }"
      @tabClick="tabClick"
      ref="tabControl1"
      v-show="isTabFixes"
    />
    <!-- 把所有要滚动的组件放到 <scroll> 移动端滚动组件里 3监听滚动 不加:会被当成字符型变量
 @scroll=""接收子组件传过来的信息  :pullUpLoad="true" 开启上拉加载更多 @pullingUp="loadMore"-->
    <scroll
      class="contentasd"
      ref="scroll"
      :probe-type="3"
      @scroll="contentScroll"
      :pull-up-load="true"
      @pullingUp="loadMore"
    >
      <!-- 使用轮播图组件并且把轮播图的数据传过去 -->
      <home-swipt :banners="banners" @swiperImageLoad="swiperImageLoad()" />
      <!--精品推荐组件并且把-精品推荐的数据传过去  -->
      <recommend-view :recommends="recommends" />
      <!-- 本周流行组件 -->
      <feature-view />
      <!--:titles="['流行','新款','精选']" 把('流行','新款','精选')传给子组件的titles属性
      @tabClick="tabClick" 接收子组件传过来的索引,用来判断要显示的模块(流行,新款,精选)  -->
      <tab-control
        :titles="['流行', '新款', '精选']"
        @tabClick="tabClick"
        ref="tabControl2"
      />
      <!-- 使用商品组件并把商品对应的数据传过去 -->
      <goods-list :goods="showGoods" />
    </scroll>

    <!-- .native 监听组件的修饰符  返回顶部按钮-->
    <back-top @click.native="backCLick" v-show="isShowBackTop" />
  </div>
</template>

<script>
/**
 *  这个项目的组件
 **/
// 导入轮播图组件
import HomeSwipt from "./chidComps/HomeSwipt.vue";
// 导入-精品推荐组件
import RecommendView from "./chidComps/RecommendView";
// 导入本周流行组件
import FeatureView from "./chidComps/FeatureView.vue";

/**
 *  公共的组件
 **/
// 导入顶部导航组件
import NavBar from "components/common/navbar/NavBar.vue";
//流行,新款,精选之间切换的组件
import TabControl from "components/cortent/tabControl/TabControl";
// 商品组件
import GoodsList from "components/cortent/goods/GoodsList.vue";
// 移动端滚动插件的组件
import Scroll from "components/common/scroll/Scroll";
// 导入混入函数
import { itemListenerMixin, backTopMixin } from "common/mixin";

/**
 *  网络相关的组件
 * */
// 导入请求首页数据的函数
import { getHomeMgltidata, getHomeGoods } from "network/home.js";

export default {
  name: "Home",
  components: {
    HomeSwipt,
    RecommendView,
    FeatureView,
    TabControl,
    NavBar,
    GoodsList,
    Scroll,
  },
  // 使用混入  混入内的生命周期函数会比自身的生命周期函数先调用
  mixins: [itemListenerMixin, backTopMixin],
  data() {
    return {
      // 把请求过来的数据保存起来
      // 轮播图的数据
      banners: [],
      // -精品推荐的数据
      recommends: [],
      gootds: {
        // 流行的数据  page页码 具体的数据
        pop: { page: 0, list: [] },
        // 新款
        new: { page: 0, list: [] },
        // 精选
        sell: { page: 0, list: [] },
      },
      // 决定显示那一个模块(流行,新款,精选) 默认显示流行模块
      currentTpe: "pop",
      // 流行\新款\精选组件内的元素距离顶部的距离
      tabOffsetTop: 0,
      // 是否吸顶
      isTabFixes: false,
      //  保存离开当前页面时的位置
      saveY: 0,
    };
  },
  //计算属性
  computed: {
    showGoods() {
      return this.gootds[this.currentTpe].list;
    },
  },
  // 生命周期函数-created 组件创建完成时触发
  created() {
    // 发送网络请求
    // 1.请求多个数据 (轮播图和精品组件的数据)
    this.getHomeMgltidata();

    // 2.请求商品的数据
    this.getHomeGoods("pop");
    this.getHomeGoods("new");
    this.getHomeGoods("sell");
  },
  // 进入当前页面时调用
  activated() {
    //或者加这个  刷新一下数据
    this.$refs.scroll.refresh();
    // 调用scrollTo函数滚动到指定的位置 x y 所需的时间(不能给0,不然有时网络延迟数据没加载,就会出现问题)
    this.$refs.scroll.scrollTo(0, this.saveY, 0);
  },
  // 离开当前页面时调用
  deactivated() {
    // 1.保存Y值
    // this.$refs.scroll.scroll.y 获取滚动插件滚动到的Y轴位置
    this.saveY = this.$refs.scroll.getScrollY();

    // 2.取消首页的全局事件监听
    this.$bus.$off("itemImgLoad", this.itemImgListener);
  },

  // 组件挂载完之后调用
  mounted() {
    // 已经在混入里使用
    // 这个地方img标签确实被挂载,但是其中的图片还没有占据高度
    // 1.图片加载完成的事件监听
    //this.$refs.scroll.refresh 把refresh 函数传过出(没有调用)
    //  debounce 使用防抖函数
    // const refresh = debounce(this.$refs.scroll.refresh, 100);
    // 这个步骤是落后的写法 可以在滚动插件里设置 observeDOM: true,变化的观察(进行同步数据的)
    // 监听item中的图片加载完成   this.$bus.$on 接收事件总线的事件
    // 对监听的事件进行保存
    //  this.itemImgListener =  () => {
    // 调用refresh()方法重新计算图片的高度,如果图片没有固定高度,数据请求慢的时候,滚动的插件可能
    // 就会出现计算问题,导致页面滚动不流畅。
    // refresh();
    // }
    //  this.$bus.$on("imageLoadaa", this.itemImgListener);
  },
  methods: {
    /**
     * 事件监听相关的方法
     */
    //  决定显示那一个模块(流行,新款,精选)
    tabClick(index) {
      switch (index) {
        case 0:
          this.currentTpe = "pop";
          break;
        case 1:
          this.currentTpe = "new";
          break;
        case 2:
          this.currentTpe = "sell";
          break;
        default:
          break;
      }

      // 让顶部的流行\新款\精选组件的选择 和 中间的同步
      this.$refs.tabControl1.currentIndex = index;
      this.$refs.tabControl2.currentIndex = index;
    },
    // 返回顶部按钮
    // backCLick() {
    //   // this.$refs.scroll(滚动的组件).scroll(里面的对象).scrollTo(0,0,500)（对象的方法）
    //   //  this.$refs.scroll.scroll.scrollTo(0,0,500);  或者
    //   //  this.$refs.scroll(滚动的组件).scrollTo(里面的方法)  x轴的位置,y轴的位置,用时
    //   this.$refs.scroll.scrollTo(0, 0, 500);
    // },
    //  滚动到的位置  是否显示返回顶部的组件
    contentScroll(postiton) {
      // 1.判断返回顶部按钮是否显示
      this.listenShowBackTop(postiton);

      // 2.决定tabOffsetTop是否吸顶(position:fixed)
      this.isTabFixes = -postiton.y > this.tabOffsetTop;
    },
    // 上拉加载更多
    loadMore() {
      // 调用请求商品数据函数,把当前显示的模块类型传过去(流行,新款,精选),请求更多的商品数据数据
      this.getHomeGoods(this.currentTpe);
      // console.log('上拉加载更多');
    },
    //  流行\新款\精选组件内的元素距离顶部的距离 $el获取里面的子组件
    swiperImageLoad() {
      this.tabOffsetTop = this.$refs.tabControl2.$el.offsetTop;
    },

    /**
     * 网络请求相关的方法
     */
    // 1.请求多个数据
    getHomeMgltidata() {
      // 调用getHomeMgltidata模块拿到请求结果
      getHomeMgltidata().then((res) => {
        //函数里的数据在函数执行完毕之后,会被回收所以把请求过来的数据分别给对应的变量保存起来
        this.banners = res.data.banner.list;
        this.recommends = res.data.recommend.list;
      });
    },
    // 2.请求商品的数据
    getHomeGoods(type) {
      // 动态获取数据的页数 如果传过来的数据type=pop,那么this.gootds[type]===this.gootd.pop
      const page = this.gootds[type].page + 1;
      getHomeGoods(type, page).then((res) => {
        //  把请求过来的数据都追加给this.gootds[type].list  ...res解析里面所有的数据
        this.gootds[type].list.push(...res.data.list);
        // 获取完数据之后把页码加1
        this.gootds[type].page += 1;

        // 必须手动调用finishPullUp()方法才能再次上拉加载
        this.$refs.scroll.finishPullUp();
      });
    },
  },
};
</script>

<style scoped>
#home {
  position: relative;
  /* vh就是当前屏幕可见高度的1%，也就是说
  height:100vh == height:100%;
  但是当元素没有内容时候，设置height:100%，该元素不会被撑开，此时高度为0，
  但是设置height:100vh，该元素会被撑开屏幕高度一致。 */
  height: 100vh; /* 不受内容的影响 */
}
.home-nav {
  background-color: var(--color-tint);
  color: aliceblue;
  z-index: 9;
}
.tabControl {
  /* position: sticky; 基于用户的滚动位置来定位。
   粘性定位的元素是依赖于用户的滚动，在 position:relative 与 position:fixed 定位之间切换。 */
  /* position: sticky;
  top: 44px;
  z-index: 9; */

  position: absolute;
  top: 44px;
  left: 0;
  right: 0;
  z-index: 9;
}
/* .contentasd{
  任何长度值都可以使用calc()函数进行计算
  height: calc(100% - 93px);
  overflow: hidden;
  margin-top: 44px;
} */
.contentasd {
  position: absolute;
  top: 44px;
  bottom: 49px;
  left: 0;
  right: 0;
  overflow: hidden;
}
</style>